[Unity]URPでオブジェクトモーションブラーを使う 您所在的位置:网站首页 unity shader lod [Unity]URPでオブジェクトモーションブラーを使う

[Unity]URPでオブジェクトモーションブラーを使う

2022-12-31 21:21| 来源: 网络整理| 查看: 265

本記事はQualiArts Advent Calendar 2022 10日目の記事です。

オブジェクトモーションブラーとは?

オブジェクトモーションブラーとはその名前の通り、高速に変化するオブジェクトに対してかかるブラーです。

オブジェクトモーションブラーOFF オブジェクトモーションブラーON URPに搭載されているカメラモーションブラー

URPにはMotionBlurのVolumeが存在します。 しかしこれはカメラモーションブラーといい、カメラの移動によってかかるブラーのため、上記のような高速で回転するオブジェクトにはブラーがかかりません。

URPのモーションブラーOFF URPのモーションブラーON PostProcessingStack V2に搭載されているオブジェクトモーションブラー

一方でPostProcessingStack V2(以下PostProcessing)にはオブジェクトモーションブラーが実装されています。

そこで今回はPostProcessingに搭載されているオブジェクトモーションブラーをURPに移植することでURPでオブジェクトモーションブラーを使えるようにします。

配布プロジェクト

本解説で作成したプロジェクトはこちらで公開しています。

解説

本記事ではURPのRenderFeatureやVolumeの仕組みをある程度理解している方を対象にしています。

またオブジェクトモーションブラーの動作原理については、私自身が十分に理解しておらず、詳細な情報を伝えることができませんが、興味がある方はA Fast and Stable Feature-Aware Motion Blur Filterの論文をお読みください。

環境 Unity2021.3.13f1 Universal Render Pipeline 12.1.7 処理を移植する VolumeComponentの移植

まずオブジェクトモーションブラーパラメーターをURPで実装します。 PostProcessingではここで実装さています。

これによりオブジェクトモーションブラーのパラメーターをVolumeComponentから設定できるようになります。 スクリーンショット 2022-12-04 20.37.02.png

using UnityEngine.Rendering; [System.Serializable, VolumeComponentMenu("Custom/Object Motion Blur")] public class ObjectMotionBlur : VolumeComponent { public ClampedFloatParameter shutterAngle = new ClampedFloatParameter(0, 0, 360); public ClampedIntParameter sampleCount = new ClampedIntParameter(8, 4, 32); public bool IsActive() { return active && shutterAngle.overrideState && shutterAngle.value > 0 && sampleCount.value > 0; } } シェーダーの移植

次にオブジェクトモーションブラーを実現するシェーダーをPostProcessingから移植します。

PostProcessingではここで実装されている処理になります。

移植後のシェーダー Shader "Hidden/PostEffect/ObjectMotionBlur" { HLSLINCLUDE #pragma target 3.0 #include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // SourceTexture TEXTURE2D(_SourceTex); float4 _SourceTex_TexelSize; // Camera depth texture TEXTURE2D_X_FLOAT(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture); // Camera motion vectors texture TEXTURE2D(_MotionVectorTexture); SAMPLER(sampler_MotionVectorTexture); float4 _MotionVectorTexture_TexelSize; // Packed velocity texture (2/10/10/10) TEXTURE2D(_VelocityTex); SAMPLER(sampler_VelocityTex); float2 _VelocityTex_TexelSize; // NeighborMax texture TEXTURE2D(_NeighborMaxTex); SAMPLER(sampler_NeighborMaxTex); float2 _NeighborMaxTex_TexelSize; // Velocity scale factor float _VelocityScale; // TileMax filter parameters int _TileMaxLoop; float2 _TileMaxOffs; // Maximum blur radius (in pixels) half _MaxBlurRadius; float _RcpMaxBlurRadius; // Filter parameters/coefficients half _LoopCount; // struct VaryingsDefault // { // float4 vertex : SV_POSITION; // float2 texcoord : TEXCOORD0; // float2 texcoordStereo : TEXCOORD1; // }; // ----------------------------------------------------------------------------- // Prefilter float Linear01DepthPPV2(float z) { float isOrtho = unity_OrthoParams.w; float isPers = 1.0 - unity_OrthoParams.w; z *= _ZBufferParams.x; return (1.0 - isOrtho * z) / (isPers * z + _ZBufferParams.y); } // Velocity texture setup half4 FragVelocitySetup(Varyings i) : SV_Target { // Sample the motion vector. float2 v = SAMPLE_TEXTURE2D(_MotionVectorTexture, sampler_MotionVectorTexture, i.uv).rg; // Apply the exposure time and convert to the pixel space. v *= (_VelocityScale * 0.5) * _MotionVectorTexture_TexelSize.zw; // Clamp the vector with the maximum blur radius. v /= max(1.0, length(v) * _RcpMaxBlurRadius); // Sample the depth of the pixel. half d = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.uv),_ZBufferParams); // Pack into 10/10/10/2 format. return half4((v * _RcpMaxBlurRadius + 1.0) * 0.5, d, 0.0); } half2 MaxV(half2 v1, half2 v2) { return dot(v1, v1)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有